package org.ecpkn.PAGridSim.core.configuration;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

public class Configuration {

	public static final class Const {

		public static final int CHANGE_NODE_FREQUENCY = -300;

		// Project parameters
		public static final String CUSTOMIZED_ENTITY_PACKAGE = "Customized_Entity_Package";

		// GridSim parameters
		public static final String SIMULATION_NAME = "Simulation_Name";
		public static final String USER_COUNTS = "User_Counts";
		public static final String RESOURCE_SHARE_MODE = "Resource_Share_Mode";
		public static final String WORK_DAYS = "Work_Days";
		public static final String TOTAL_NODE_NUMBER = "Total_Node_Number";

		// Report
		public static final String SIMULATIONGANT_CHARTNAME = "SimulationGant_ChartName";
		public static final String POWER_WORKLOAD_CHARTNAME = "Power_Workload_ChartName";
		public static final String REPORT_PATH = "Report_Path";
		public static final String DECIMAL_FORMAT = "Decimal_Format";
		public static final String POWER_UNIT = "Power_Unit";

		// TaskCreation
		public static final String SIMULATION_TASKNUMBER = "Simulation_TaskNumber";
		public static final String STANDARD_RATING = "Standard_Rating";
		// Different policy tests
		// Machine type
		public static final String SYSTEM_ARCHITECTURE = "System_Architecture";

		public static final String MAX_RATING = "Max_Rating";
		public static final String POWER_STATIQUE = "Power_Statique";
		public static final String POWER_COEFFICIENT = "Power_coefficient";
		public static final String SIMULATION_MACHINE = "Simulation_Machine";
		public static final String TURNOFF_POWER = "Turnoff_Power";
		// Policy
		public static final String SIMULATION_POLICY = "Simulation_Policy";
		public static final String SIMULATION_OPTIMIZATION = "Simulation_Optimization";
		// WorkloadType
		public static final String TASKS_ARRIVING_MODE = "Tasks_Arriving_Mode";
		public static final String ARRIVING_MODE_START_TOGETHER = "Start_Together";
		public static final String ARRIVING_MODE_RANDOM = "Random";

		public static final String MIN_PERIOD = "Min_Period";

		public static final String EXPERIMENT_LENGTH = "Experiment_Length";

		public static final String TASK_CREATOR = "Task_Creator";

		public static final String TASK_REPEAT_LIMIT = "Task_Repeat_Limit";

		public static final String WORKLOAD_UNIT = "Workload_Unit";

		public static final String GANTT_SUBTASK_DIFCOLOR = "Gantt_SubTask_DifColor";
		public static final String GANTT_SUBTASK_LABEL = "Gantt_SubTask_Label";
		public static final String POWER_UPPER_BOUND = "Power_Upper_Bound";
		

	}

	private volatile static Configuration configInstance;
	private Document doc;

	public static Configuration getInstance() {
		if (configInstance == null) {
			synchronized (Configuration.class) {
				if (configInstance == null) {
					configInstance = new Configuration();
				}
			}
		}
		return configInstance;
	}

	private Configuration() {

		DocumentBuilderFactory oDocumentBuilderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder oDocumentBuilder = null;
		try {
			oDocumentBuilder = oDocumentBuilderFactory.newDocumentBuilder();

			// Create a file info
			File oXmlFile = new File(System.getProperty("user.dir")
					+ "//config.xml");

			// Load the file into an XML document

			doc = oDocumentBuilder.parse(oXmlFile);

		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}

	}

	public long getParameterLong(String parameterName) {
		return Long.parseLong(doc.getElementsByTagName(parameterName).item(0)
				.getTextContent());
	}

	public int getParameterInt(String parameterName) {
		return Integer.parseInt(doc.getElementsByTagName(parameterName).item(0)
				.getTextContent());
	}

	public double getParameterDouble(String parameterName) {
		if (doc.getElementsByTagName(parameterName).item(0) != null) {
			return Double.parseDouble(doc.getElementsByTagName(parameterName)
					.item(0).getTextContent());
		} else {
			return 0.0;
		}
	}

	public Float getParameterFloat(String parameterName) {
		if (doc.getElementsByTagName(parameterName).item(0) != null) {
			return Float.parseFloat(doc.getElementsByTagName(parameterName)
					.item(0).getTextContent());
		} else {
			return null;
		}
	}

	public String getParameterString(String parameterName) {
		if (doc.getElementsByTagName(parameterName).item(0) != null) {
			return doc.getElementsByTagName(parameterName).item(0)
					.getTextContent();
		} else {
			return null;
		}
	}

	public boolean getParameterBoolean(String parameterName) {
		if (doc.getElementsByTagName(parameterName).item(0) != null) {
			return Boolean.parseBoolean(doc.getElementsByTagName(parameterName)
					.item(0).getTextContent());
		} else {
			return false;
		}
	}

	public Double toDecimalFormatDouble(Double value) {
		return Double.valueOf(toDecimalFormat(value));
	}

	public String toDecimalFormat(Double value) {
		String format = doc.getElementsByTagName(Const.DECIMAL_FORMAT).item(0)
				.getTextContent();
		DecimalFormat df = new java.text.DecimalFormat(format);
		return df.format(value);
	}

	public String toDecimalFormatIntString(int gridletID) {
		String repeatNumber = Configuration.getInstance().getParameterString(
				Const.TASK_REPEAT_LIMIT);
		repeatNumber = repeatNumber.substring(1, repeatNumber.length());
		DecimalFormat df = new java.text.DecimalFormat("0" + repeatNumber);
		return df.format(gridletID);
	}

}
